package com.ruoyi.web.controller.system;

import java.util.*;
import java.util.concurrent.TimeUnit;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.model.ForgotBody;
import com.ruoyi.common.core.domain.model.SmsEntity;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.framework.datasource.DynamicDataSource;
import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder;
import com.ruoyi.framework.utils.AliYunSendSmsUtil;
import com.ruoyi.framework.utils.QueryCustomerVo;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.tenant.domain.SysAdvice;
import com.ruoyi.tenant.domain.SysTenant;
import com.ruoyi.tenant.service.ISysAdviceService;
import com.ruoyi.tenant.service.ISysTenantService;
import com.ruoyi.tenant.utils.AddDataSourceUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.system.service.ISysMenuService;

import javax.sql.DataSource;

/**
 * 登录验证
 *
 * @author ruoyi
 */
@RestController
public class SysLoginController
{
    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private ISysTenantService sysTenantService;

    @Autowired
    private ISysAdviceService sysAdviceService;

    @Autowired
    private ISysTenantService iSysTenantService;

    @Autowired
    private AddDataSourceUtil addDataSourceUtil;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private RedisCache redisCache;

    @Value("${tenant.expire}")
    private Integer expireDay;

    /**
     * 登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody)
    {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid(),loginBody.getTenantId());
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo()
    {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        user.setTenantId(DynamicDataSourceContextHolder.getDataSourceType());
        if("master".equals(user.getTenantId().toLowerCase())){
            ajax.put("empower", 1);
            ajax.put("expiringday", 0);
            ajax.put("advicecount", 1);
        }else {
            SysTenant sysTenant = sysTenantService.selectTenantByTenantId(user.getTenantId());
            ajax.put("empower", sysTenant.getEmpower());
            int expiringday = expireDay - DateUtils.differentDaysByMillisecond(new Date(), sysTenant.getCreateDate()) >= 0 ?
                    expireDay - DateUtils.differentDaysByMillisecond(new Date(), sysTenant.getCreateDate()) : 0;
            ajax.put("expiringday", expiringday);

            SysAdvice advice = new SysAdvice();
            advice.setTenantid(user.getTenantId());
            int adviceCount = sysAdviceService.selectSysAdviceList(advice).size();
            ajax.put("advicecount", adviceCount);
        }
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters()
    {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(menuService.buildMenus(menus));
    }

    /**
     * 获取短信验证码
     *
     * @param
     * @return 结果
     */
    @PostMapping("/sendSmsCode")
    public AjaxResult sendSmsCode(@RequestBody ForgotBody forgotBody) throws Exception {
        // 手机号码
       String phoneNumber = forgotBody.getTelePhone().trim();
        // 校验手机号
        SysUser user = sysUserService.selectUserByPhonenumber(phoneNumber);
        if (StringUtils.isNull(user)) {
            return AjaxResult.error("用户手机号：" + phoneNumber+ " 不存在");
        }else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
            return AjaxResult.error("对不起，您的账号：" + phoneNumber+ " 已被删除");
        }else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            return AjaxResult.error("对不起，您的账号：" + phoneNumber+ " 已停用");
        }

        // 生成短信验证码
        String smsCode = "" + (int)((Math.random()*9+1)*100000);
        // 发送短信（实际按系统业务实现）
        SmsEntity entity = new SmsEntity();
        entity.setPhoneNumber(phoneNumber);
        entity.setSmsCode(smsCode);

        QueryCustomerVo send = new QueryCustomerVo();
        send.setContactPhone(phoneNumber);
        send.setContactCode(smsCode);
        //发送华为云短信
        //sendSmsUtil.sendSms(send);
        //阿里云短信
        AliYunSendSmsUtil.SendSms(send);

        // 保存redis缓存
        String uuid = IdUtils.simpleUUID();
        String verifyKey = CacheConstants.CAPTCHA_SMSCODE_KEY + uuid;
        redisCache.setCacheObject(verifyKey, smsCode, 5, TimeUnit.MINUTES);

        return AjaxResult.success(uuid);
    }

    /**
     * 获取短信验证码
     *
     * @param
     * @return 结果
     */
    @PostMapping("/forgotPwd")
    public AjaxResult forgotPwd(@RequestBody ForgotBody forgotBody) throws Exception {
        // 手机号码
        String phoneNumber = forgotBody.getTelePhone().trim();
        // 校验手机号
        SysUser user = sysUserService.selectUserByPhonenumber(phoneNumber);
        if (StringUtils.isNull(user)) {
            return AjaxResult.error("用户手机号：" + phoneNumber+ " 不存在");
        }else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
            return AjaxResult.error("对不起，您的账号：" + phoneNumber+ " 已被删除");
        }else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            return AjaxResult.error("对不起，您的账号：" + phoneNumber+ " 已停用");
        }
        String verifyKey = CacheConstants.CAPTCHA_SMSCODE_KEY + forgotBody.getSmsUuid();
        String code = redisCache.getCacheObject(verifyKey);
        if(!forgotBody.getSmsCode().equals(code)){
            return AjaxResult.error("验证码不正确");
        }

        return AjaxResult.success();
    }

    /**
     *
     * @param
     * @return 结果
     */
    @PostMapping("/subForgotPwd")
    public AjaxResult subForgotPwd(@RequestBody ForgotBody forgotBody) throws Exception {
        // 手机号码
        String phoneNumber = forgotBody.getTelePhone().trim();
        if(StringUtils.isEmpty(phoneNumber)){
            return AjaxResult.error("修改失败");
        }
        String verifyKey = CacheConstants.CAPTCHA_SMSCODE_KEY + forgotBody.getSmsUuid();
        String code = redisCache.getCacheObject(verifyKey);
        if(!forgotBody.getSmsCode().equals(code)){
            return AjaxResult.error("修改失败");
        }
        // 校验手机号
        SysUser user = sysUserService.selectUserByPhonenumber(phoneNumber);
        if (StringUtils.isNull(user)) {
            return AjaxResult.error("用户手机号：" + phoneNumber+ " 不存在");
        }
        sysUserService.resetUserPwd(user.getUserName(), SecurityUtils.encryptPassword(forgotBody.getPassword()));
        redisCache.deleteObject(verifyKey);
        Map<String, String> data = new HashMap<>(2);
        data.put("tenantId" , forgotBody.getTenantId() );
        data.put("userName" , user.getUserName() );
        return AjaxResult.success(data);
    }

}
